
Berta.Settings = new Class(function() {
	return {
		
		statics: {
			_instance: null, // Singleton instance
			instance: function(options) {
				if(!Berta.Settings._instance) {
					Berta.Settings._instance = new Berta.Settings(options);
				}
				
				return Berta.Settings._instance;
			}
		},
		
		defaults: {
			callbacks: {
				onLoad:null
			}
		},
		
		loaded: {
			'definitions.entry-settings': {
				'gallery': { type: 'gallery' }
			}
		},
		

		//   .______    __    __  .______    __       __    ______    ////////////////////////////////////////////////////////////
		//   |   _  \  |  |  |  | |   _  \  |  |     |  |  /      |   ////////////////////////////////////////////////////////////
		//   |  |_)  | |  |  |  | |  |_)  | |  |     |  | |  ,----'   ////////////////////////////////////////////////////////////
		//   |   ___/  |  |  |  | |   _  <  |  |     |  | |  |        ////////////////////////////////////////////////////////////
		//   |  |      |  `--'  | |  |_)  | |  `----.|  | |  `----.   ////////////////////////////////////////////////////////////
		//   | _|       \______/  |______/  |_______||__|  \______|   ////////////////////////////////////////////////////////////
	
		constructor: function(options) {
			this.options = jQuery.extend(true, {}, this.defaults, options);
		},
		
		
		load: function(items, onLoadComplete) {
			if(!this.loadQueue) this.loadQueue = [];
			if(!this.loadServerQueue || isNaN(this.itemsInServerQueue)) this.itemsInServerQueue = 0;
			
			
			
			if(!this.loadCallbacks) this.loadCallbacks = [];
			this.loadQueue.push.apply(this.loadQueue, items);	// Add item by item
			
			if(this.loadCallbacks.indexOf(onLoadComplete) < 0) {
				this.loadCallbacks.push(onLoadComplete);
			}
			
			if(!this.loading) {
				this.loading = true;
				this._(loadQueue)();
			}
		},
		
		getSetting: function(collection, groupOrPath, name) {
			if(name) groupOrPath += '.' + name;
			
			if(this.loaded.hasOwnProperty('values.' + collection)) {
				if (this.loaded['values.' + collection] && groupOrPath in this.loaded['values.' + collection]) {
					return this.loaded['values.' + collection][groupOrPath];
				} else {
					$.logWarn('Berta.Settings::getSetting: "', collection, '" does not contain value for "' + groupOrPath + '" - using default!');
					var def = this.getDefinition(collection, groupOrPath, name);
					if(def && ("default" in def)) {
						return def["default"];
					}
				}
			} else {
				$.logError('Berta.Settings::getSetting: "', collection, '" values not loaded for "' + groupOrPath + '"!');
			}
			
			return null;
		},
		getDefinition: function(collection, groupOrPath, name) {
			if(name) groupOrPath += '.' + name;

			if(this.loaded.hasOwnProperty('definitions.' + collection)) {
				if (this.loaded['definitions.' + collection] && groupOrPath in this.loaded['definitions.' + collection]) {
					return this.loaded['definitions.' + collection][groupOrPath];
				} else {
					$.logWarn('Berta.Settings::getDefinition: "', collection, '" does not contain definition for "' + groupOrPath + '"!');
				}
			} else {
				$.logError('Berta.Settings::getDefinition: "', collection, '" definition not loaded for "' + groupOrPath + '"!');
			}
			
			return null;
		},
		
		
		setSetting: function(collection, path, value) {
			if(this.loaded.hasOwnProperty('values.' + collection)) {
				if(!this.loaded['values.' + collection]) {
					this.loaded['values.' + collection] = {};
				}
				
				this.loaded['values.' + collection][path] = value;
				
				this.setChanged(collection);
				
			} else {
				$.logError('Berta.Settings::setSetting: "', collection, '" values not loaded for "' + path + '"!');
			}
		},
		
		
		checkForChanges: function() {
			// check if settings have changed on server
			this._(load)(true);
		},
		setChanged: function(collection) {
			// just delete from local storage
			Berta.Storage.instance().remove('collections.' + collection);
		},
		
		
		getSettings: function(collection) {
			if(!isEmpty(this.loaded['values.' + collection])) {
				return this.loaded['values.' + collection];
			} else {
				$.logWarn('Berta.Settings: "', collection, '" values not loaded!');
			}
			return null;
		},
		getDefinitions: function(collection, id /* for template-settings */) {
			if(!isEmpty(this.loaded['definitions.' + collection])) {
				return this.loaded['definitions.' + collection];
			} else {
				$.logWarn('Berta.Settings: "', collection, '" definitions not loaded!');
			}
			return null;
		},



		clearLocalSettingsCache: function(templateId, valuesOnly) {
			if(templateId === true) templateId = Berta.Options.template_id;

			$.log('Berta.Settings::clearLocalSettingsCache: templateId = ' + templateId + ', valuesOnly = ' + valuesOnly);

			if(templateId) {
				// Current template settings
				if(!valuesOnly) Berta.Storage.instance().remove('definitions.template-settings.' + templateId);
				Berta.Storage.instance().remove('values.template-settings.' + templateId);

			} else {
				// Global settings
				if(!valuesOnly) Berta.Storage.instance().remove('definitions.settings');
				Berta.Storage.instance().remove('values.settings');
			}
		}
		
		
	
	};
	

	//   .______   .______     __  ____    ____  ___   .___________. _______    //////////////////////////////////////////////////
	//   |   _  \  |   _  \   |  | \   \  /   / /   \  |           ||   ____|   //////////////////////////////////////////////////
	//   |  |_)  | |  |_)  |  |  |  \   \/   / /  ^  \ `---|  |----`|  |__      //////////////////////////////////////////////////
	//   |   ___/  |      /   |  |   \      / /  /_\  \    |  |     |   __|     //////////////////////////////////////////////////
	//   |  |      |  |\  \--.|  |    \    / /  _____  \   |  |     |  |____    //////////////////////////////////////////////////
	//   | _|      | _| `.___||__|     \__/ /__/     \__\  |__|     |_______|   //////////////////////////////////////////////////

	
	function loadQueue() {
		var atLeastOneLoadable = false;
		while(itemToLoad = this.loadQueue.shift()) {
			// First, try to get the item from local storage
			this.loaded[itemToLoad] = Berta.Storage.instance().load(itemToLoad);
			//$.log(this.loaded[itemToLoad]);
			if(isEmpty(this.loaded[itemToLoad])) {
				var itemSplit = itemToLoad.split('.');
				
				// Construct route...
				var r = Berta.Route.get(
							'get:' + itemSplit[1], 
							{ 'id': itemSplit[2] }, 
							{ 'filter' : itemSplit[0] }
						);
				
				this.itemsInServerQueue++;
				Berta.Server.instance().get(r, this._(onLoadComplete, [itemToLoad]));
				atLeastOneLoadable = true;
			}
		}
		
		if(!atLeastOneLoadable) {
			this._(completeQueue)();
		}
	}
	function onLoadComplete(itemLoaded, xhrId, response) {
		
		if(response.error) {
			$.logError('Berta.Settings: Loading \'' + itemLoaded + '\' failed! Error: ', response.errorMessage);
		} else {
			if(response.json) {
				this.loaded[itemLoaded] = response.json;
				
			} else {
				$.logError('Berta.Settings: Parsing \'' + itemLoaded + '\' failed! ', response);
			}
			
			// Save loaded item into sessionStorage
			Berta.Storage.instance().save(itemLoaded, this.loaded[itemLoaded]);
		}
		
		this.itemsInServerQueue--;
		if(this.itemsInServerQueue <= 0) {
			this._(completeQueue)();
		}
		
	}
	
	function completeQueue() {
		$.log('Berta.Settings: Queue complete!');
		while(func = this.loadCallbacks.shift()) {
			func();
		}
		this.loading = false;
	}
		
	
	/*function load(forceFromServer) {
		if(forceFromServer) {
			this.collections.settings = undefined;
			this.collections.templateSettings = undefined;
			this.definitions.settings = undefined;
			this.definitions.templateSettings = undefined;
		} else {
			this.collections['settings'] = Berta.Storage.instance().load('collections.settings');
			this.collections['template-settings'] = Berta.Storage.instance().load('collections.template-settings');
			this.definitions['settings'] = Berta.Storage.instance().load('definitions.settings');
			this.definitions['template-settings'] = Berta.Storage.instance().load('definitions.template-settings');
		}
		
		// settings
		if (isEmpty(this.collections.settings)) {
			//this.requests.collections.settings.isLoading = true;
			//this.options.server.get(this.requests.collections.settings.url, this.requests.collections.settings.data, null, this._(onLoadComplete, ['collections', 'settings']));
			Berta.Server.instance().get(Berta.Routes.settings.values, this._(onLoadComplete, ['collections', 'settings']));
			
		}
		if (isEmpty(this.definitions.settings)) {
			//this.requests.definitions.settings.isLoading = true;
			Berta.Server.instance().get(Berta.Routes.settings.definitions, this._(onLoadComplete, ['definitions', 'settings']));
		}
		
		// template settings
		if (isEmpty(this.collections["template-settings"])) {
			//this.requests.collections["template-settings"].isLoading = true;
			Berta.Server.instance().get(Berta.Routes["template-settings"].values, this._(onLoadComplete, ['collections', 'template-settings']));
		}
		if (isEmpty(this.definitions["template-settings"])) {
			//this.requests.definitions["template-settings"].isLoading = true;
			Berta.Server.instance().get(Berta.Routes["template-settings"].definitions, this._(onLoadComplete, ['definitions', 'template-settings']));
		}
	}*/

	
	function isEmpty(obj) {
		if(!obj) return true;
		
		for(var prop in obj) {
			if(obj.hasOwnProperty(prop))
				return false;
		}
		
		return true;
	}
	
}());

